package com.zhb.tools

import android.app.Application
import android.app.ProgressDialog
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Bitmap.CompressFormat
import android.graphics.BitmapFactory
import android.graphics.Matrix
import android.net.Uri
import com.zhb.tools.ZLog.e
import java.io.*
import java.net.URL

class FileUtil {
    /**
     * 根据指定的文件名创建文件
     *
     * @param fileName
     * @return
     */
    private fun createSdFile(path: String?, fileName: String): File? {
        return try {
            val file = File(path, fileName)
            if (!file.exists()) {
                file.createNewFile()
            }
            file
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }

    /**
     * @param path
     * @param fileName
     * @param input
     * @return
     */
    fun writeToSdCardFromInputStream(
        path: String?,
        fileName: String,
        input: InputStream,
        myDialog: ProgressDialog
    ): File? {
        var file: File? = null
        var out: OutputStream? = null
        try {
            checkAndCreateDir(path)
            file = createSdFile(path, fileName)
            val temp = ByteArray(1024 * 4)
            out = FileOutputStream(file)
            var len: Int
            var total = 0
            while (input.read(temp).also { len = it } != -1) {
                out.write(temp, 0, len)
                total += len
                myDialog.progress = total
            }
            out.flush()
        } catch (e: IOException) {
            e.printStackTrace()
        } finally {
            try {
                out!!.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
        return file
    }

    /**
     * 根据地址获得输入流
     *
     * @return
     */
    fun getInputStream(path: String?): InputStream? {
        var input: InputStream? = null
        val url: URL
        try {
            url = URL(path)
            input = url.openConnection().getInputStream()
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return input
    }

    /**
     * 将指定文件，转成Bitmap对象
     *
     * @return
     */
    fun getPathBitmap(path: String?): Bitmap {
        val bitmap: Bitmap
        bitmap = BitmapFactory.decodeFile(path)
        return bitmap
    }

    /**
     * 图片压缩
     *
     * @param fromFile 文件全路径
     * @param toFile   要写入的文件的路径
     * @param width    图片的宽度
     * @param height   图片的高度
     * @param quality
     */
    fun transImage(fromFile: String?, toFile: String?, width: Int, height: Int, quality: Int) {
        try {
            val bitmap = BitmapFactory.decodeFile(fromFile)
            val bitmapWidth = bitmap.width
            val bitmapHeight = bitmap.height
            // 缩放图片的尺寸
            val scaleWidth = width.toFloat() / bitmapWidth
            val scaleHeight = height.toFloat() / bitmapHeight
            val matrix = Matrix()
            matrix.postScale(scaleWidth, scaleHeight)
            // 产生缩放后的Bitmap对象
            val resizeBitmap =
                Bitmap.createBitmap(bitmap, 0, 0, bitmapWidth, bitmapHeight, matrix, false)
            // save file
            val myCaptureFile = File(toFile)
            val out = FileOutputStream(myCaptureFile)
            if (resizeBitmap.compress(CompressFormat.JPEG, quality, out)) {
                out.flush()
                out.close()
            }
            if (!bitmap.isRecycled) {
                bitmap.recycle() // 记得释放资源，否则会内存溢出
            }
            if (!resizeBitmap.isRecycled) {
                resizeBitmap.recycle()
            }
        } catch (e: FileNotFoundException) {
            e.printStackTrace()
        } catch (ex: IOException) {
            ex.printStackTrace()
        }
    }

    companion object {
        /**
         * 检查并创建制定目录
         *
         * @param path
         * @return
         */
        fun checkAndCreateDir(path: String?): Boolean {
            val fileDir = File(path)
            if (!fileDir.exists()) {
                fileDir.mkdir()
                return false
            }
            return true
        }

        /**
         * 把注入流换成字符串
         *
         * @param inputStream
         * @return
         */
        fun getStreamString(inputStream: InputStream?): String? {
            if (inputStream != null) {
                var tBufferedReader: BufferedReader? = null
                try {
                    tBufferedReader = BufferedReader(InputStreamReader(inputStream, "UTF-8"))
                    val tStringBuffer = StringBuffer()
                    var sTempOneLine: String?
                    while (tBufferedReader.readLine().also { sTempOneLine = it } != null) {
                        tStringBuffer.append(sTempOneLine)
                    }
                    return tStringBuffer.toString()
                } catch (ex: Exception) {
                    ex.printStackTrace()
                } finally {
                    try {
                        tBufferedReader!!.close()
                    } catch (e: IOException) {
                        e.printStackTrace()
                    }
                }
            }
            return null
        }

        /**
         * 读取数据 输入流
         */
        fun readStream(inputStream: InputStream?): ByteArray? {
            val outstream = ByteArrayOutputStream()
            return try {
                val buffer = ByteArray(5 * 1024)
                var len: Int
                while (inputStream!!.read(buffer).also { len = it } != -1) {
                    outstream.write(buffer, 0, len)
                }
                outstream.toByteArray()
            } catch (e: Exception) {
                null
            } finally {
                try {
                    outstream.close()
                    inputStream!!.close()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }
        }

        /**
         * 读取应用assets目录文件内容
         *
         * @param context
         * @param fileName
         * @return
         */
        @JvmStatic
        fun getNativeFile(context: Application, fileName: String?): String? {
            try {
                return getStreamString(context.assets.open(fileName!!))
            } catch (e: IOException) {
                e.printStackTrace()
            }
            return ""
        }

        /**
         * 将一个字符串转化为输入流
         */
        private fun getStringStream(sInputString: String?): InputStream? {
            if (sInputString != null && sInputString.trim { it <= ' ' } != "") {
                try {
                    return ByteArrayInputStream(sInputString.toByteArray(charset("UTF-8")))
                } catch (ex: Exception) {
                    ex.printStackTrace()
                }
            }
            return null
        }

        /**
         * 向文本文件中写入内容或追加新内容,如果append为true则直接追加新内容,<br></br>
         * 如果append为false则覆盖原来的内容<br></br>
         *
         * @param path
         * @param content
         * @param append
         */
        fun writeFile(path: String, fileName: String, content: String?, append: Boolean) {
            var path = path
            checkAndCreateDir(path) // 创建目录
            path = path + File.separator + fileName
            var writefile: File
            try {
                writefile = File(path)
                if (!writefile.exists()) {
                    writefile.createNewFile()
                    writefile = File(path) // 重新实例化
                }
                // 将字符串转化为输入流
                val `is` = getStringStream(content)

                // 创建输出流 append 判断是否追加内容
                val fw = FileOutputStream(writefile, append)
                val temp = ByteArray(1024 * 4)
                var len: Int
                while (`is`!!.read(temp).also { len = it } != -1) {
                    fw.write(temp, 0, len)
                }
                fw.flush()
                fw.close()
            } catch (ex: Exception) {
            }
        }

        fun getPic(input: InputStream?): Bitmap {
            return BitmapFactory.decodeStream(input)
        }

        /**
         * 缩放图片
         *
         * @param bitmap
         * @param screenWidth
         * @return
         */
        fun resizeImage(bitmap: Bitmap?, screenWidth: Int): Bitmap? {
            if (bitmap == null) {
                return null
            }
            val width = bitmap.width // 获取图片的宽度
            val height = bitmap.height // 获取图片的高度
            val newHeight = screenWidth * height / width // 根据屏幕的宽度，计算按比较缩放后的高度
            val scaleWidth = screenWidth.toFloat() / width
            val scaleHeight = newHeight.toFloat() / height
            val matrix = Matrix()
            matrix.postScale(scaleWidth, scaleHeight)
            val resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true)
            // 释放资源
            if (bitmap != null && !bitmap.isRecycled) {
                bitmap.recycle()
            }
            return resizedBitmap
        }

        /**
         * 根据高度缩放
         *
         * @param bitmap
         * @param screenHeight
         * @return
         */
        fun resizeImageH(bitmap: Bitmap?, screenHeight: Int): Bitmap? {
            if (bitmap == null) {
                return null
            }
            val width = bitmap.width // 获取图片的宽度
            val height = bitmap.height // 获取图片的高度
            val newWidth = width * screenHeight / height
            val scaleWidth = newWidth.toFloat() / width
            val scaleHeight = screenHeight.toFloat() / height
            val matrix = Matrix()
            matrix.postScale(scaleWidth, scaleHeight)
            val resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true)
            // 释放资源
            if (bitmap != null && !bitmap.isRecycled) {
                bitmap.recycle()
            }
            return resizedBitmap
        }

        /**
         * 原图bitmap对象 缩放的比例
         */
        fun toBig(bmp: Bitmap, scale: Float): Bitmap {
            val bmpWidth = bmp.width
            val bmpHeight = bmp.height

            /* 计算这次要放大/缩小的比例 */
            val scaleWidth = bmpWidth * scale
            val scaleHeight = bmpHeight * scale

            /* 产生reSize后的Bitmap对象 */
            val matrix = Matrix()
            matrix.postScale(scaleWidth, scaleHeight)
            return Bitmap.createBitmap(bmp, 0, 0, bmpWidth, bmpHeight, matrix, true)
        }

        /**
         * Bitmap 保存为文件
         *
         * @param bmp
         * @param filename
         * @return
         */
        fun saveFile(bmp: Bitmap, filePath: String, filename: String): Boolean {
            val format = CompressFormat.JPEG
            val tempFile = File(filePath)
            if (!tempFile.exists()) {
                tempFile.mkdirs()
            }
            val quality = 100
            var stream: OutputStream? = null
            try {
                val filenewName = filePath + File.separator + filename
                val file = File(filenewName)
                if (file.exists()) {
                    file.delete()
                }
                try {
                    file.createNewFile()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
                stream = FileOutputStream(filenewName)
            } catch (e: FileNotFoundException) {
                e(e.message)
                //            e.printStackTrace();
            }
            return bmp.compress(format, quality, stream)
        }

        fun saveFile(data: ByteArray?, filePath: String?, fileName: String?) {
            val pathFile = File(filePath)
            val imageFile = File(filePath, fileName)
            imageFile.delete()
            try {
                if (!pathFile.exists()) {
                    pathFile.mkdirs()
                }
                imageFile.createNewFile()
                var outputStream: FileOutputStream? = FileOutputStream(imageFile)
                outputStream!!.write(data)
                outputStream.close()
                outputStream = null
            } catch (e: IOException) {
                e(e.message)
                // e.printStackTrace();
            }
        }

        fun decodeUriAsBitmap(context: Context, uri: Uri): Bitmap? {
            var bitmap: Bitmap? = null
            try {
                val mContent =
                    readStream(context.contentResolver.openInputStream(Uri.parse(uri.toString())))
                bitmap = getBitmap(mContent)
            } catch (e: Exception) {
                e.printStackTrace()
            }
            return bitmap
        }

        fun getBitmap(all: ByteArray?): Bitmap? {
            val bmp: Bitmap
            try {
                // path文件的byte
                if (all!!.size > 1024 * 1024) {
                    val options = BitmapFactory.Options()
                    options.inSampleSize = 5 // 图片缩放比例
                    bmp = BitmapFactory.decodeByteArray(all, 0, all.size, options)
                } else {
                    bmp = BitmapFactory.decodeByteArray(all, 0, all.size)
                }
                return bmp
            } catch (o: OutOfMemoryError) {
            } catch (oom: Exception) {
            }
            return null
        }
    }
}